package com.gdk.ksoft.ui.logins;

import android.app.Activity;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

import com.gdk.ksoft.R;
import com.gdk.ksoft.data.common.ConstantData;
import com.gdk.ksoft.data.common.SystemData;
import com.gdk.ksoft.data.entry.datas.BaseResultModel;
import com.gdk.ksoft.data.entry.tables.BankTable;
import com.gdk.ksoft.data.entry.tables.ContactorTable;
import com.gdk.ksoft.data.entry.tables.CustomerAreaTable;
import com.gdk.ksoft.data.entry.tables.CustomerDebtTable;
import com.gdk.ksoft.data.entry.tables.CustomerLatLngTable;
import com.gdk.ksoft.data.entry.tables.CustomerPriceTable;
import com.gdk.ksoft.data.entry.tables.CustomerTable;
import com.gdk.ksoft.data.entry.tables.CustomerTypeTable;
import com.gdk.ksoft.data.entry.tables.CxqhGoodsTable;
import com.gdk.ksoft.data.entry.tables.CxqhSaleDetailTable;
import com.gdk.ksoft.data.entry.tables.CxqhSaleTable;
import com.gdk.ksoft.data.entry.tables.CxqhTable;
import com.gdk.ksoft.data.entry.tables.DeliverGoodsTable;
import com.gdk.ksoft.data.entry.tables.ExceptionTable;
import com.gdk.ksoft.data.entry.tables.GoodsBrandTable;
import com.gdk.ksoft.data.entry.tables.GoodsGroupDetailTable;
import com.gdk.ksoft.data.entry.tables.GoodsGroupTable;
import com.gdk.ksoft.data.entry.tables.GoodsModuleTable;
import com.gdk.ksoft.data.entry.tables.GoodsTable;
import com.gdk.ksoft.data.entry.tables.OneGoodsTypesDetailTable;
import com.gdk.ksoft.data.entry.tables.OneGoodsTypesTable;
import com.gdk.ksoft.data.entry.tables.PriceTable;
import com.gdk.ksoft.data.entry.tables.SaleBuyOtherCustomerTable;
import com.gdk.ksoft.data.entry.tables.SaleBuyOtherGiftTable;
import com.gdk.ksoft.data.entry.tables.SaleBuyOtherGoodsTable;
import com.gdk.ksoft.data.entry.tables.SaleBuyOtherLevelTable;
import com.gdk.ksoft.data.entry.tables.SaleBuyOtherTable;
import com.gdk.ksoft.data.entry.tables.SaleBuySelfCustomerTable;
import com.gdk.ksoft.data.entry.tables.SaleBuySelfGoodsTable;
import com.gdk.ksoft.data.entry.tables.SaleBuySelfLevelTable;
import com.gdk.ksoft.data.entry.tables.SaleBuySelfTable;
import com.gdk.ksoft.data.entry.tables.SaleGoodsTable;
import com.gdk.ksoft.data.entry.tables.SaleManRouteTable;
import com.gdk.ksoft.data.entry.tables.SaleManTable;
import com.gdk.ksoft.data.entry.tables.SaleStatisticsTable;
import com.gdk.ksoft.data.entry.tables.SaleTable;
import com.gdk.ksoft.data.entry.tables.ShoppingCartGoodsTable;
import com.gdk.ksoft.data.entry.tables.UnsoldGoodsTable;
import com.gdk.ksoft.assembly.widget.ProgressBar;
import com.gdk.ksoft.assembly.utils.system.FileUtils;
import com.gdk.ksoft.assembly.utils.extensions.MD5Utils;
import com.gdk.ksoft.assembly.utils.system.NetworkUtils;
import com.gdk.ksoft.assembly.utils.system.SQLiteUtils;
import com.google.gson.Gson;
import com.google.gson.internal.StringMap;
import com.google.gson.reflect.TypeToken;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.db.annotation.Column;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseStream;
import com.lidroid.xutils.http.client.HttpRequest;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.lidroid.xutils.view.annotation.event.OnClick;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 下载数据页面
 */
public class DownloadTableActivity extends Activity {
    /**
     * 下载时间标示，存储于本地数据中
     */
    public static final String DOWNLOAD_DATE_TIME = "download_time";

    public static final String[] methodNames = {
            "Cx_YeWuYuan2","Cx_PinPai", "Cx_JiaGe", "Cx_ShangPinJldw",
            "Cx_ShangPin","Cx_LianXiRen", "Cx_DiQu", "Cx_KeHuLx", "Cx_KeHu", "Cx_KeHuShdz",
            "Cx_KeHuJiaGe", "Cx_KeHuQianKuan", "Cx_WeiShouDuiLie", "Cx_YinHangZhangHu",
            "Cx_CuXiaoMzbpKh","Cx_CuXiaoMzbpSp","Cx_CuXiaoMzbpMzjt","Cx_CuXiaoMzbp",
            "Cx_CuXiaoMztpKh","Cx_CuXiaoMztpZp","Cx_CuXiaoMztpSp","Cx_CuXiaoMztpMzjt","Cx_CuXiaoMztp",
            "Cx_FenZu","Cx_FenZuSp","Cx_TongPinDuoWei","Cx_TongPinDuoWeiSp"
    };

    public static final String[] desTexts = {
            "正在下载业务员数据...","正在下载品牌数据...", "正在下载价格数据...", "正在下载商品计量单位数据...",
            "正在下载商品数据...","正在下载联系人数据...", "正在下载地区数据...", "正在下载客户类型数据...",
            "正在下载客户数据...", "正在下载客户收货地址数据...", "正在下载客户价格数据...", "正在下载客户欠款数据...",
            "正在下载客户未售队列数据...", "正在下载银行收款账户数据...","正在下载买赠本品客户数据...","正在下载买赠本品商品数据...",
            "正在下载买赠本品买赠阶梯数据...","正在下载买赠本品促销数据...","正在下载买赠它品客户数据...",
            "正在下载买赠它品赠送商品数据...","正在下载买赠它品商品数据...","正在下载买赠它品等级数据...",
            "正在下载买赠它品促销数据...","正在下载商品分组数据...","正在下载分组商品数据...","正在下载同品多味分组数据",
            "正在下载同品多味商品数据..."
    };

    /**
     * 需要经常改变的表类
     */
    public static final Class<?>[] TABLES_CAHNGED = {
            SaleManTable.class,//业务员表 0

            GoodsBrandTable.class,//品牌表 1
            PriceTable.class,//价格表 2
            GoodsModuleTable.class,//商品计量单位表 3
            GoodsTable.class,//商品表 4
            UnsoldGoodsTable.class,//未售商品列表 5
            SaleBuySelfCustomerTable.class,//买赠本品客户表 6
            SaleBuySelfGoodsTable.class,//买赠本品商品表 7
            SaleBuySelfLevelTable.class,//买赠本品阶梯表 8
            SaleBuySelfTable.class,//买赠本品表 9
            SaleBuyOtherCustomerTable.class,//买赠它品客户表 10
            SaleBuyOtherGiftTable.class,//买赠它品赠送表 11
            SaleBuyOtherGoodsTable.class,//买赠它品商品表 12
            SaleBuyOtherLevelTable.class,//买赠它品等级表 13
            SaleBuyOtherTable.class,//买赠它品促销表 14

            ContactorTable.class,//联系人表 15
            CustomerAreaTable.class,//客户地区表 16
            CustomerTypeTable.class,//客户类型表 17
            CustomerTable.class,//客户表 18
            DeliverGoodsTable.class,//送货地址表 19
            CustomerPriceTable.class,//客户价格表 20
            CustomerDebtTable.class,//客户收欠款表 21
            BankTable.class,//银行账户数据表 22

            GoodsGroupTable.class,//商品分组表 23
            GoodsGroupDetailTable.class,//商品分组细则表 24
            OneGoodsTypesTable.class,//同品多味分组表 25
            OneGoodsTypesDetailTable.class,//同品多味商品表 26

            SaleManRouteTable.class,//业务员行径记录表 27
            ExceptionTable.class//异常信息表 28
    };

    /**
     * 固化的表类数组
     */
    public static final Class[] TABLES_FIXED = {
            SaleTable.class,//销售表
            SaleGoodsTable.class,//销售商品表
            SaleStatisticsTable.class,//销售结算表
            ShoppingCartGoodsTable.class,//购物车商品表
            CustomerLatLngTable.class,//客户经纬度表
            CxqhTable.class,//车销请货库存表
            CxqhSaleTable.class,//车销请货销售单表
            CxqhSaleDetailTable.class,//车销请货详单表
            CxqhGoodsTable.class//撤销请货购物车商品表
    };

    @ViewInject(R.id.pdownloadTable_txtTip)
    private TextView txtTip;//提示进度文字
    @ViewInject(R.id.pdownloadTable_pb)
    private ProgressBar pbDownload;//进度条数据
    @ViewInject(R.id.pdownloadTable_txtProgress)
    private TextView txtProgress;//下载进度值
    @ViewInject(R.id.pdownloadTable_txtMin)
    private TextView txtMin;//下载进度min值
    @ViewInject(R.id.pdownloadTable_txtMax)
    private TextView txtMax;//下载进度max值
    private boolean isDownloadTables = false;

    private DbUtils dbUtils;//数据库操作对象
    private Context context;//上下文对象

    public static final int MSG_DOWNLOAD_START = 0x001;//开始下载
    public static final int MSG_DOWNLOAD_INIT = 0x002;//下载参数初始化
    public static final int MSG_DOWNLOAD_DOING = 0x003;//下载中
    public static final int MSG_DOWNLOAD_ERROR = 0x004;//下载出错
    public static final int MSG_DOWNLOAD_DONE = 0x005;//下载完成

    public Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_DOWNLOAD_START:
                    txtTip.setText("等待下载...");
                    break;
                case MSG_DOWNLOAD_INIT:
                    txtTip.setText("正在初始化...");
                    int max = Integer.valueOf(msg.obj.toString());
                    pbDownload.setMax(max);
                    txtMax.setText("0/" + max);
                    txtMin.setText("0");
                    break;
                case MSG_DOWNLOAD_DOING:
                    txtTip.setText(msg.obj.toString());
                    txtMin.setText(String.valueOf(msg.arg1));
                    txtMax.setText(msg.arg1 + "/" + msg.arg2);
                    txtProgress.setText(((int) ((float) msg.arg1 / msg.arg2 * 100)) + "%");
                    pbDownload.setProgress(msg.arg1);
                    break;
                case MSG_DOWNLOAD_ERROR:
                    txtTip.setText(msg.obj.toString());
                    break;
                case MSG_DOWNLOAD_DONE:
                    txtTip.setText("下载完成");
                    DownloadTableActivity.this.setResult(Activity.RESULT_OK);
                    DownloadTableActivity.this.finish();
                    break;
            }
        }
    };

    /**
     * 初始化下载
     */
    public void initDownload(DbUtils dbUtils) {
        isDownloadTables = true;
        handler.sendEmptyMessage(MSG_DOWNLOAD_START);
        for (Class<?> item : TABLES_CAHNGED) {//再创建
            createTables(item, dbUtils);
        }
        //创建需要长期存在的表
        for (Class<?> item : TABLES_FIXED) {
            createTables(item, dbUtils);
        }
    }

    /**
     * 如果表不存在创建数据表
     * @param cls
     */
    public void createTables(Class<?> cls,DbUtils dbUtils) {
        try {
            if(!dbUtils.tableIsExist(cls))
                dbUtils.createTableIfNotExist(cls);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Window window = getWindow();
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        setContentView(R.layout.activity_download_table);
        context = DownloadTableActivity.this;//获取上下文对象
        if(Build.VERSION.SDK_INT>=11) //当SDK版本>=11时可执行
            setFinishOnTouchOutside(false);
        ViewUtils.inject(this);
        this.dbUtils = SQLiteUtils.getInstance(this).getDbUtils();
        downloadAllTablesByAsyncTask(context);//开始下载数据
    }

    /**
     * 取消下载
     *
     * @param view
     */
    @OnClick(value = {R.id.pdownloadTable_txtCancel})
    public void onCancelDownload(View view) {
        this.setResult(Activity.RESULT_CANCELED);
        this.finish();
        context = null;
        isDownloadTables = false;//取消数据下载
        if(dbUtils!=null){
            dbUtils = null;//释放数据库对象
        }
//        ApkUtils.restartApplication(this);
    }

    /**
     * 下载所有数据表
     */
    public void downloadAllTablesByAsyncTask(final Context context) {
        new AsyncTask<Void, Void, Void>() {
            private String errorMessage = null;//错误信息
            @Override
            protected Void doInBackground(Void... params) {
                initDownload(dbUtils);//初始化下载
                handler.obtainMessage(MSG_DOWNLOAD_INIT, methodNames.length).sendToTarget();
                int index = 0;//下载索引值
                while (index < methodNames.length) {
                    if (!isDownloadTables) return null;
                    if (errorMessage != null) {//下载出错
                        isDownloadTables = false;
                        handler.obtainMessage(MSG_DOWNLOAD_ERROR,errorMessage).sendToTarget();
                        this.cancel(true);
                        break;
                    }
                    try {
                        Thread.sleep(200);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        System.out.println((index + 1) + "-----> " + desTexts[index] + "：" + methodNames[index]);
                        if (!downloadTable(context,dbUtils,methodNames[index], index,false)) {
                            errorMessage = "网络出错，请重试!";
                            isDownloadTables = false;
                            handler.obtainMessage(MSG_DOWNLOAD_ERROR,errorMessage).sendToTarget();
                            this.cancel(true);
                            return null;
                        }
                        handler.obtainMessage(MSG_DOWNLOAD_DOING, (index + 1), methodNames.length, desTexts[index]).sendToTarget();
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("----->数据表【"+desTexts[index]+"】下载出错："+e.getMessage());
                        errorMessage = "网络出错，请重试!";
                        isDownloadTables = false;
                        handler.obtainMessage(MSG_DOWNLOAD_ERROR,errorMessage).sendToTarget();
                        this.cancel(true);
                        return null;
                    }
                    index++;
                }
                handler.sendEmptyMessage(MSG_DOWNLOAD_DONE);
                return null;
            }
        }.execute();
    }

    /**
     * 下载数据表
     * @param context
     * @param dbUtils 数据库操作对象
     * @param methodName 方法名称
     * @param position 执行的方法的索引
     * @param isDelOldData 是否删除老数据
     * @return
     * @throws Exception
     */
    public synchronized static boolean downloadTable(final Context context,final DbUtils dbUtils,final String methodName,final int position,final boolean isDelOldData) throws Exception {
        if(context == null||!NetworkUtils.isNetAvailable(context)) return false;//下载页面已经关闭
        switch (position) {
            case 0://业务人员表
                return saveDataToTable(context,dbUtils,methodName,position,SaleManTable.class,true);
            case 1://品牌表
                return saveDataToTable(context,dbUtils,methodName,position,GoodsBrandTable.class,isDelOldData);
            case 2://商品价格表
                return saveDataToTable(context,dbUtils,methodName,position,PriceTable.class,isDelOldData);
            case 3://商品计量单位表
                return saveDataToTable(context,dbUtils,methodName,position,GoodsModuleTable.class,isDelOldData);
            case 4://商品表
                return saveDataToTable(context,dbUtils,methodName,position,GoodsTable.class,isDelOldData);
            case 5://联系人表
                return saveDataToTable(context,dbUtils,methodName,position,ContactorTable.class,isDelOldData);
            case 6://客户地区表
                return saveDataToTable(context,dbUtils,methodName,position,CustomerAreaTable.class,isDelOldData);
            case 7://客户类型表
                return saveDataToTable(context,dbUtils,methodName,position,CustomerTypeTable.class,isDelOldData);
            case 8://客户表
                return saveDataToTable(context,dbUtils,methodName,position,CustomerTable.class,isDelOldData);
            case 9://送货地址表
                return saveDataToTable(context,dbUtils,methodName,position,DeliverGoodsTable.class,isDelOldData);
            case 10://客户价格表
                return saveDataToTable(context,dbUtils,methodName,position,CustomerPriceTable.class,isDelOldData);
            case 11://客户欠款表
                return saveDataToTable(context,dbUtils,methodName,position,CustomerDebtTable.class,isDelOldData);
            case 12://未销售表
                return saveDataToTable(context,dbUtils,methodName,position,UnsoldGoodsTable.class,isDelOldData);
            case 13://银行数据账户表
                return saveDataToTable(context,dbUtils,methodName,position,BankTable.class,isDelOldData);
            case 14://买赠本品客户数据
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuySelfCustomerTable.class,isDelOldData);
            case 15://买赠本品商品数据
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuySelfGoodsTable.class,isDelOldData);
            case 16://买赠本品赠送阶梯数据
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuySelfLevelTable.class,isDelOldData);
            case 17://买赠本品促销数据
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuySelfTable.class,isDelOldData);
            case 18://买赠它品客户表
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuyOtherCustomerTable.class,isDelOldData);
            case 19://买赠它品赠送表
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuyOtherGiftTable.class,isDelOldData);
            case 20://买赠它品商品表
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuyOtherGoodsTable.class,isDelOldData);
            case 21://买赠它品等级表
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuyOtherLevelTable.class,isDelOldData);
            case 22://买赠它品促销表
                return saveDataToTable(context,dbUtils,methodName,position,SaleBuyOtherTable.class,isDelOldData);
            case 23://商品分组表
                return saveDataToTable(context,dbUtils,methodName,position,GoodsGroupTable.class,isDelOldData);
            case 24://商品分组细则表
                return saveDataToTable(context,dbUtils,methodName,position,GoodsGroupDetailTable.class,isDelOldData);
            case 25://同品多味商品分组表
                return saveDataToTable(context,dbUtils,methodName,position,OneGoodsTypesTable.class,isDelOldData);
            case 26://同品多味商品分组细则表
                return saveDataToTable(context,dbUtils,methodName,position,OneGoodsTypesDetailTable.class,isDelOldData);
        }
        return false;
    }

    /**
     * 储存数据到网络到本地数据库
     * @param dbUtils
     * @param cls
     * @param isDelOldData
     * @return
     * @throws Exception
     */
    public static boolean saveDataToTable(final Context context,DbUtils dbUtils,String methodName,int position,final Class cls,boolean isDelOldData){
        SQLiteDatabase database = dbUtils.getDatabase();
        boolean isTransaction = false;//是否执行了事务
        boolean isExecuteOk = true;//是否执行成功
        try {
            if (!isDelOldData && dbUtils.count(cls) > 0) return true;
            String messageBody = "{\"Sjch\":\"" + SystemData.PhoneIMEI + "\"}";
            RequestParams params = new RequestParams("UTF-8");
            params.addBodyParameter("Method", methodName);
            params.addBodyParameter("Digest", MD5Utils.getMd5(methodName + messageBody + "19491001"));
            System.out.println("===========加密后的字符串：" + MD5Utils.getMd5(methodName + messageBody + "19491001") + "=================");
            params.addBodyParameter("MessageBody", "{\"Sjch\":\"" + SystemData.PhoneIMEI + "\"}");
            ResponseStream responseStream = new HttpUtils(ConstantData.NETWORK_CONNECT_TIME_OUT)
                    .configSoTimeout(ConstantData.NETWORK_READ_TIME_OUT)
                    .sendSync(HttpRequest.HttpMethod.POST, SystemData.BASE_URL, params);
            if (responseStream == null) throw new Exception("服务器返回空数据!");
            String tableString = FileUtils.stream2string(responseStream);
            System.out.println("表【" + position + "】数据是：-------->" + tableString);
            BaseResultModel model = new Gson().fromJson(tableString, BaseResultModel.class);
            if (model != null && model.Result.equals("0000")) {
                try {
                    database.beginTransaction();
                    isTransaction = true;
                    try {
                        if (dbUtils.tableIsExist(cls)) {//如果表存在，则清除所有数据
                            dbUtils.deleteAll(cls);
                        }
                    }catch (Exception e){
                        System.out.println("----->删除数据表: "+cls+"错误");
                        e.printStackTrace();
                    }
                    final Type type = new TypeToken<ArrayList<StringMap>>() {
                    }.getType();
                    List<StringMap> datalst = new Gson().fromJson(model.Data, type);
                    for (StringMap item : datalst) {
                        if(context == null){//退出操作
                            if(isTransaction){//关闭数据库事务
                                database.endTransaction();
                            }
                            return false;
                        }
                        Object itemInstance = cls.newInstance();
                        Field[] fields = cls.getDeclaredFields();
                        if(fields == null || fields.length<=0) continue;
                        for(Field field : fields){
                            field.setAccessible(true);
                            Column column = field.getAnnotation(Column.class);
                            if(column!=null) {//确定是数据库字段
                                if (!column.column().equals("djbz")) {
                                    Object obj = item.get(column.column());//获得该字段的值
                                    Type ftype = field.getType();
                                    if (ftype.equals(int.class)) {//整数型的需要转换
                                        if (obj == null) obj = "0";
                                        obj = Integer.parseInt(obj.toString().split("[.]")[0]);
                                    } else if (ftype.equals(float.class)) {//浮点型的需要转换
                                        if (obj == null) obj = "0";
                                        obj = Float.parseFloat(obj.toString());
                                    } else if (ftype.equals(double.class)) {
                                        if (obj == null) obj = "0";
                                        obj = Double.parseDouble(obj.toString());
                                    } else if (ftype.equals(String.class)) {
                                        if (obj == null) obj = "";
                                    }
                                    field.set(itemInstance, obj);
                                    continue;
                                }
                                field.set(itemInstance, 1);//如果是单机标识【1-网络标志】
                            }
                        }
                        dbUtils.save(itemInstance);
                    }
                    if(isTransaction) {//已经执行了事务
                        database.setTransactionSuccessful();
                    }
                } catch (Exception e) {
                    isExecuteOk = false;
                    e.printStackTrace();
                }finally{
                    if(isTransaction) {//已经执行了事务
                        database.endTransaction();
                    }
                }
            }
        }catch (Exception e){
            isExecuteOk = false;
            e.printStackTrace();
        }
        return isExecuteOk;
    }

}
